<?php

namespace maotool\util;

use maotool\file\DirUtil;
use maotool\file\FileUtil;
use maotool\object\StrUtil;

class PathUtil
{

    /**
     * 路径
     * @param ...$path
     * @return string
     */
    public static function path(...$path)
    {
        $path = ArrayUtil::join($path, "/");
        if (StrUtil::startsWith($path, 'project:')) {
            $path = str_replace("project:", PathUtil::projectPath(), $path);
        } else if (StrUtil::startsWith($path, 'maotool:')) {
            $path = str_replace("maotool:", PathUtil::maotoolPath(), $path);
        } else if (StrUtil::startsWith($path, 'system-temp:')) {
            $path = str_replace("system-temp:", DirUtil::getSystemTemp(), $path);
        } else if (StrUtil::startsWith($path, 'create-system-temp:')) {
            $path = str_replace("create-system-temp:", DirUtil::createSystemTemp(), $path);
        } else if (StrUtil::startsWith($path, 'create-system-temp-file:*.')) {
            $path = FileUtil::createSystemTempFile(IdUtil::simpleUUID() . str_replace("create-system-temp-file:*.", ".", $path));
        } else if (StrUtil::startsWith($path, 'create-system-temp-file:*')) {
            $path = FileUtil::createSystemTempFile(IdUtil::simpleUUID() . str_replace("create-system-temp-file:*", ".tmp", $path));
        } else if (StrUtil::startsWith($path, 'create-system-temp-file:')) {
            $path = FileUtil::createSystemTempFile(str_replace("create-system-temp-file:", "", $path));
        } else if (StrUtil::startsWith($path, 'vendor:')) {
            $path = str_replace("vendor:", PathUtil::projectPath() . "/vendor", $path);
        }
        $list = preg_split('/([\/\\\\]+)/', $path, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        foreach ($list as &$item) {
            // 如果路径包含空格或特殊字符，且未用双引号包裹，则添加双引号
            if (preg_match('/\s/', $item) && !preg_match('/^".*"$/', $item)) {
                $item = '"' . $item . '"';
            }
        }
        return preg_replace("/[\/\\\\]+/", DirUtil::$DIRECTORY_SEPARATOR, StrUtil::join($list, ""));
    }

    /**
     * 文件是否存在
     * @param $path
     * @return bool
     */
    public static function exist($path)
    {
        if (FileUtil::exist($path)) {
            return true;
        } else if (DirUtil::exist($path)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 是否是路径
     * @param $path
     * @return bool
     */
    public static function isPath($path)
    {
        // 正则表达式模式，匹配常见的路径格式
        $pattern = '/^(?:\/{2})?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)*$/';
        // 使用 preg_match 函数进行匹配
        if (preg_match($pattern, $path)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 应用根目录
     */
    public static function projectPath()
    {
        $project = self::parent(__DIR__, 8);
        $projectFile = FileUtil::path($project, "composer.json");
        $projectVendor = DirUtil::path($project, "vendor");
        $maotoolFile = FileUtil::path($project, "vendor", "wl4837", "maotool", "composer.json");
        if (file_exists($projectFile) && is_file($projectFile)
            && file_exists($projectVendor) && is_dir($projectVendor)
            && file_exists($maotoolFile) && is_file($maotoolFile)) {
            return DirUtil::path($project);
        } else {
            return PathUtil::maotoolPath();
        }
    }

    /**
     * 框架目录
     */
    public static function maotoolPath()
    {
        $path = self::parent(__DIR__, 5);
        $file = FileUtil::path($path, "composer.json");
        if (file_exists($file) && is_file($file)) {
            return DirUtil::path($path);
        }
        return false;
    }

    /**
     * composer 路径
     * @return string
     */
    public static function projectComposerPath()
    {
        $path = self::projectPath();
        if ($path === false) {
            return false;
        }
        $file = FileUtil::path($path, "composer.json");
        if (file_exists($file) && is_file($file)) {
            return $file;
        } else {
            return false;
        }
    }

    /**
     * package 路径
     * @return string
     */
    public static function projectPackagePath()
    {
        $path = self::projectPath();
        if ($path === false) {
            return false;
        }
        $file = FileUtil::path($path, "package.json");
        if (file_exists($file) && is_file($file)) {
            return $file;
        } else {
            return false;
        }
    }

    /**
     * Env 路径
     * @return bool|string
     */
    public static function projectEnvPath()
    {
        $path = self::projectPath();
        if ($path === false) {
            return false;
        }
        $file = FileUtil::path($path, ".env");
        if (file_exists($file) && is_file($file)) {
            return $file;
        } else {
            return false;
        }
    }

    /**
     * composer 路径
     * @return string
     */
    public static function maotoolComposerPath()
    {
        $path = self::maotoolPath();
        if ($path === false) {
            return false;
        }
        $file = FileUtil::path($path, "composer.json");
        if (file_exists($file) && is_file($file)) {
            return $file;
        } else {
            return false;
        }
    }

    /**
     * 路径名称
     * @param $path
     * @return string
     */
    public static function name($path)
    {
        $path = self::path($path);
        return basename($path);
    }

    /**
     * 上级路径
     * @param string $path
     * @param int $level
     * @return string
     */
    public static function parent($path, $level = 1)
    {
        $path = self::path($path);
        $list = preg_split('/([\/\\\\]+)/', $path, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        while (true) {
            if (count($list) >= 2 && $level > 0) {
                $item = array_pop($list);
                if ($item == "/" || $item == "\\") {
                    continue;
                } else {
                    --$level;
                }
            } else {
                if (count($list) >= 2) {
                    $item = array_pop($list);
                    if ($item != "/" && $item != "\\") {
                        $list[] = $item;
                    }
                }
                return ArrayUtil::join($list, "");
            }
        }
    }

}